package org.zxp.thread.base;

import org.junit.Test;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @program: zxp-thread-test
 * @description: 线程状态演示
 * @author: X-Pacific zhang
 * @create: 2019-05-06 16:00
 **/
public class ThreadState {
    public static void main(String[] args) {
        //NEW
        Thread thread1 = new Thread();
        System.out.println("thread1 `s state:" + thread1.getState());

        //RUNNABLE
        Thread thread2 = new Thread(() ->
        {
            int a = 0;
            for (int i = 0; i < 100000; i++) {
                a++;
            }
        });
        thread2.start();
        sleep(100);
        System.out.println("thread2 `s state:" + thread2.getState());

        //TIMED_WAITING 有时间限制的WAITING
//        调用了以下方法的线程会进入TIMED_WAITING：
//        Thread#sleep()
//        Object#wait() 并加了超时参数
//        Thread#join() 并加了超时参数
//        LockSupport#parkNanos()
//        LockSupport#parkUntil()
        Thread thread3 = new Thread(() ->
        {
            synchronized (ThreadState.class) {
                sleep(200000000);
            }
        }
        );
        thread3.start();
        sleep(100);
        System.out.println("thread3 `s state:" + thread3.getState());
        //BLOCKED
        Thread thread4 = new Thread(() ->
        {
            synchronized (ThreadState.class) {
            }
        }
        );
        thread4.start();
        sleep(200);
        System.out.println("thread4 `s state:" + thread4.getState());
        //WAITING
//        当线程调用以下方法时会进入WAITING状态：
//        Object#wait() 而且不加超时参数
//        Thread#join() 而且不加超时参数
//        LockSupport#park()
        Object obj = new Object();
        Thread thread5 = new Thread(() ->
        {
            synchronized (obj) {
                try {
                    obj.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        );
        thread5.start();
        sleep(200);
        System.out.println("thread5 `s state:" + thread5.getState());

        sleep(10000);
    }

    private static void sleep(long sleepTime) {
        try {
            Thread.sleep(sleepTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    @Test
    public void testBlock() {
        Thread thread = new Thread(() ->
        {
            while (true) {
//                sleep(10);
            }
        }
        );
        thread.start();
        while (true){
            System.out.println(thread.getState());
        }
    }


    @Test
    public void testBlockState(){
        Lock lock = new ReentrantLock();
        Thread t1 = new Thread(() -> {
            synchronized (ThreadState.class){
                try {
                    Thread.sleep(10000000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread t2 = new Thread(() -> {
            synchronized (ThreadState.class){
            }
        });
        t1.start();t2.start();
        Thread t3 = new Thread(() -> {
            lock.lock();
            try {
                Thread.sleep(10000000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock.unlock();
        });
        Thread t4 = new Thread(() -> {
            lock.lock();
            lock.unlock();
        });
        t3.start();t4.start();
        while (true){
            System.out.println(t2.getState());
        }
    }
}
